package aduros.net {

import flash.events.IEventDispatcher;
import flash.utils.ByteArray;

import com.threerings.util.Log;

import com.whirled.net.MessageReceivedEvent;

public class RemoteProvider
{
    public static const log :Log = Log.getLog(RemoteProvider);

    public function RemoteProvider (
        dispatcher :IEventDispatcher, serviceName :String, switchboard :Function)
    {
        _dispatcher = dispatcher;
        _serviceName = serviceName;
        _switchboard = switchboard;

        _dispatcher.addEventListener(MessageReceivedEvent.MESSAGE_RECEIVED, onMessage);
    }

    protected function onMessage (event :MessageReceivedEvent) :void
    {
        if (event.name == _serviceName) {
            try {
                var ba :ByteArray = event.value as ByteArray;
                var handlerName :String = ba.readUTF(); // Remove the handler name

                var args :Array = new Array(ba.readInt());
                for (var ii :int = 0; ii < args.length; ++ii) {
                    args[ii] = ba.readObject();
                }

                var manager :Object;
                if (event.isFromServer()) {
                    manager = _switchboard();
                } else {
                    manager = _switchboard(event.senderId); // Get the manager
                    args.unshift(event.senderId); // Prepend the caller id
                }

                var handler :Function = manager.REMOTE::[handlerName] as Function;
                handler.apply(manager, args);

            } catch (error :Error) {
                log.warning("Error calling service handler",
                    "handler", handlerName, "senderId", event.senderId,
                    error);
            }
        }
    }

    public function unload () :void
    {
        _dispatcher.removeEventListener(MessageReceivedEvent.MESSAGE_RECEIVED, onMessage);
    }

    protected var _dispatcher :IEventDispatcher;
    protected var _serviceName :String;
    protected var _switchboard :Function;
}

}
